﻿namespace API.Filters;

/// <summary>
/// 防止输入参数sql注入
/// </summary>
public class SqlInjectFilter : ActionFilterAttribute
{
    /// <summary>
    /// 重写执行方法
    /// </summary>
    /// <param name="context"></param>
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        try
        {
            //获取参数集合
            var ps = context.ActionDescriptor.Parameters;
            if (ps.Count() == 0)
            {
                return;
            }
            bool isExist = false;
            //遍历参数集合
            foreach (var p in ps)
            {
                if (context.ActionArguments.ContainsKey(p.Name))
                {
                    if (p.ParameterType.IsGenericType)
                    {
                        continue;
                    }
                    if (context.ActionArguments[p.Name] != null)
                    {
                        //当参数是str
                        if (p.ParameterType.Equals(typeof(string)))
                        {
                            context.ActionArguments[p.Name] = SQLInjectHelper.SQLFilter(context.ActionArguments[p.Name].ToString(), out isExist);
                            if (isExist)
                            {
                                break;
                            }
                        }
                        else if (p.ParameterType.IsClass)//当参数是一个实体
                        {
                            isExist = PostModelFieldFilter(p.ParameterType, context.ActionArguments[p.Name]);
                            if (isExist)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            if (isExist)
            {
                context.Result = new OkObjectResult(new ResultModel
                {
                    code = -99,
                    msg = "该搜索条件会引起系统安全隐患，暂不支持"
                });
                return;
            }
            base.OnActionExecuting(context);
        }
        catch (Exception ex)
        {
            Log.WriteException(ex);
        }
    }
    /// <summary>
    /// 遍历实体字符串属性
    /// </summary>
    /// <param name="type"></param>
    /// <param name="obj"></param>
    /// <returns></returns>
    private bool PostModelFieldFilter(Type type, object obj)
    {
        try
        {
            bool isExist = false;
            if (obj != null)
            {
                foreach (var item in type.GetProperties())
                {
                    if (item.PropertyType.IsGenericType)
                    {
                        continue;
                    }
                    if (item.GetValue(obj) != null)
                    {
                        //当参数是str
                        if (item.PropertyType.Equals(typeof(string)))
                        {
                            string value = item.GetValue(obj).ToString();
                            item.SetValue(obj, SQLInjectHelper.SQLFilter(value, out isExist));
                            if (isExist)
                            {
                                break;
                            }
                        }
                        else if (item.PropertyType.IsClass)
                        {
                            // item.SetValue(obj, PostModelFieldFilter(item.PropertyType, item.GetValue(obj)));
                        }
                    }
                }
            }
            return isExist;
        }
        catch (Exception)
        {
            throw;
        }
    }
}
